package com.linklee.Chapter3;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 本章引入 惰性求值和早求值的概念
 */

public class Chapter3Learn {

    public static void main(String[] agrs) {
        //chapter3-4
        //惰性求值的基本特征:
        //                  返回值是一个Stream类型
        //                  没有早求值语句,无法输出结果
        List<String> strings = Stream.of("1", "2", "3").collect(Collectors.toList());
        Stream streamLazy = strings.stream().filter(string -> {
            System.out.println(string);
            return string.equals("1");
        });

        //chapter3-5
        //早求值的基本特征:
        //                 返回值是另一个值,或者是空
        // 由于返回值是long型则会输出
        long filterCount = strings.stream().filter(string -> {
            System.out.println(string);
            return string.equals("1");
        }).count();
        System.out.println("符合条件的个数=====" + filterCount);

        //chapter3-9
        //对List中的每一项进行变换或者更换类型用map更好
        List<Integer> integers = strings
                .stream()
                .map(string -> Integer.parseInt(string))
                .collect(Collectors.toList());
        //或者对原list只做某些处理
        List<String> lowwerCasestrings = Stream.of("a", "b", "c").collect(Collectors.toList());
        List<String> upperCaseStrings = lowwerCasestrings
                .stream()
                .map(string -> string.toUpperCase())
                .collect(Collectors.toList());

        //chapter3-11
        //函数风格的过滤
        List<String> firstNumbicStrings = Stream.of("2aaa", "ccasd", "12323")
                .collect(Collectors.toList());
        List<String> filterFirstNumbicStrings = firstNumbicStrings.stream()
                .filter(string -> Character.isDigit(string.charAt(0)))
                .collect(Collectors.toList());

        //chapter3-12
        //合并多个流 flatMap
        // flatMap 和 map的区别是  map可以将多个流组成list
        // flatMap 可以整和多个流
        List<String> allStrings = Stream.of(
                Stream.of("1", "2", "3").collect(Collectors.toList()),
                Stream.of("a", "b", "c").collect(Collectors.toList()))
                .flatMap(stream -> stream.stream())
                .collect(Collectors.toList());
        List allStream = Stream.of(
                Stream.of("1", "2", "3").collect(Collectors.toList()),
                Stream.of("a", "b", "c").collect(Collectors.toList())
        ).map(stringstr -> stringstr.stream()).collect(Collectors.toList());

        //chapter3-13
        //求min和max 使用Comparator.comparing 去指定回去最大值/最小值的规则
        List<String> getMax = Stream.of("aaa", "a", "aa").collect(Collectors.toList());
        String maxString = getMax.stream().max(Comparator.comparing(
                string -> string.length()
        )).get();
        System.out.println("max=====" + maxString);

        String minString = getMax.stream().min(Comparator.comparing(
                string -> string.length()
        )).get();
        System.out.println("min=====" + minString);


        //chapter3-16
        //使用reduce求和
        int count = Stream.of(1, 2, 3)
                .reduce(0, (sum, element) -> {
                    System.out.println("和为======" + sum);
                    System.out.println("遍历的数为=====" + sum);
                    return sum + element;
                });

        //chapter3-17
        //使用函数式求和
        BinaryOperator<Integer> sumInteger =
                (num1, num2) -> {
                    return num1 + num2;
                };

        int sum = sumInteger.apply(
                3, sumInteger.apply(2,
                        sumInteger.apply(0, 1))
        );
        System.out.println("1,2,3的和为=====" + sum);

        //chaper3.18
        // 找到所有以a为开头的人的国家

        // 模拟创建所有国家
        Map<String, String> m1 = new HashMap<>();
        m1.put("country", "china");
        m1.put("name", "aa");
        Map<String, String> m2 = new HashMap<>();
        m2.put("country", "china");
        m2.put("name", "ab");
        Map<String, String> m3 = new HashMap<>();
        m3.put("country", "usa");
        m3.put("name", "ac");
        Map<String, String> m4 = new HashMap<>();
        m4.put("country", "uk");
        m4.put("name", "d");

        // 把所有人添加到集合中
        List<Map<String, String>> listMap = Stream.of(m1, m2, m3, m4)
                .collect(Collectors.toList());

        //filter 过滤所有名字以a开头的
        //map 将人的对象转换为所有国家的set
        // 因为set不重复,所以最后就会得出所有人的国家的不重复
        Set<String> list = listMap.stream().filter(map -> map.get("name").startsWith("a"))
                .map(map -> map.get("country"))
                .collect(Collectors.toSet());

        //chapter3.20
        //代码for循环重构
        //原代码如下

        // 假如lists中存了十张专辑,我们要找出十张专辑中超过六十秒中的曲目
        List<List<Map<String,String>>>  lists = new ArrayList<>();
        // 曲目名称的集合
        Set<String> names =new HashSet<>();
        // 遍历十张专辑
        for(List<Map<String,String>> list1:lists){
            // 遍历专辑中的所有曲目
            for(Map<String,String>map:list1){
                // 如果时长大于60秒,
                if(Integer.parseInt(map.get("time"))>60){
                    //则放到集合中去
                    names.add(map.get("name"));
                }
            }
        }

        // 运用流进行重构
        List<List<Map<String,String>>>  listsNew = new ArrayList<>();
        Set<String> namesNew = new HashSet<>();
        namesNew = listsNew.stream()
                // 1.把所有专辑的曲目合并到一起
                .flatMap(newLists->newLists.stream())
                // 2.过滤所有时长超过六十秒的歌曲
                .filter(map->Integer.parseInt(map.get("time"))>60)
                // 3.把所有符合要求的曲目替换成曲目名字
                .map(namestr->namestr.get("name"))
                // 4.然后转换成set
                .collect(Collectors.toSet());
    }


}
